package com.xtedu.examproject.filter;

import com.xtedu.examproject.entity.Menu;
import com.xtedu.examproject.entity.User;
import com.xtedu.examproject.util.RedisUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class AuthorizationFilter implements Filter {
    private List<String> excludedUrls;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String servletPath = request.getServletPath();
        if (excludedUrls.stream().anyMatch(servletPath::startsWith)) {
            filterChain.doFilter(request, response);
            return;
        }
        //权限鉴定
        HttpSession session = request.getSession();
        //User currentLogin = (User) session.getAttribute("user");
        User currentLogin=RedisUtil.getObject("session:"+session.getId(), User.class);
        //servletPath当前希望访问的接口 是否有权限
        //是否有权限的关键是servletPath有没有出现在getMenus的集合里
        List<Menu> menus = currentLogin.getMenus();
        //servletPath与menus中任何一个的getPath的值属于startWith关系时则返回真true
        if(checkAccess(servletPath,menus)){//有权访问
            filterChain.doFilter(request, response);
        }else {
            //无权访问
            response.sendRedirect("/login");
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        String excludedUrlsString = filterConfig.getInitParameter("excludedUrls");
        excludedUrls = Arrays.asList(excludedUrlsString.split(","));
    }

    public boolean checkAccess(String servletPath,List<Menu> menus){
        return  menus.stream().anyMatch(menu -> {
                    //一级比较
                    if(servletPath.startsWith("/"+menu.getPath())){
                        return true;
                    }
                    //跟孩子的比较
                    if(menu.getChildren()!=null&&checkAccess(servletPath,menu.getChildren())){
                        return true;
                    }
                    return false;
                }
        );
    }
}
